﻿using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Threading;
using System.Net;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace HCROV
{
    public class HCConnect
    {

        public delegate void Senddatas(byte[] data);
        private byte[] MsgBuffer = new byte[8];
        
        Senddatas sendbytes = new Senddatas(szyProtocol.getbytes);
        szyProtocol protocol = new szyProtocol();


        #region  模拟延时
        [DllImport("kernel32.dll")]
        static extern uint GetTickCount();
        static void Delay(uint ms)
        {
            uint start = GetTickCount();
            while (GetTickCount() - start < ms)
            {
                Application.DoEvents();
            }
        }
        #endregion

        public void Connect(string ipAdress, string port, Socket clientSocket)
        {
            //获取水下机器人的ip地址和端口
            IPAddress IP = IPAddress.Parse(ipAdress);
            Int32 Port = Int32.Parse(port);

            try
            {
                //初始化Socket，这里采用Tcp的连接方式
                IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);
                //state.workSocket = clientSocket;
                clientSocket.BeginConnect(iPEndPoint, new AsyncCallback(ConnectCallBack), clientSocket);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Warning");
            }
        }

        /// <summary>
        /// 回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ConnectCallBack(IAsyncResult ar)
        {
            try
            {
                Socket socket = (Socket)ar.AsyncState;
                socket.EndConnect(ar);
                if (IsConnect(socket)) MessageBox.Show("连接成功");
            }
            catch (SocketException)
            {
                MessageBox.Show("ConnectCallBackError");
            }
        }

        /// <summary>
        /// 接收信息的方法
        /// </summary>
        public void Receive(Socket socket)
        {
            Delay(300);
            try
            {
                socket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(),"接收信息失败");
            }
        }

        /// <summary>
        /// 接受信息的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveCallBack(IAsyncResult ar)
        {
            try
            {
                int byteRead = HCMainForm.socket.EndReceive(ar);
                if (byteRead > 0)
                {
                    MessageBox.Show(Encoding.UTF8.GetString(MsgBuffer));//测试数据有没收到

                    sendbytes(MsgBuffer);//把byte数组的值传到协议类里面
                    protocol.CheckData();//进行数据的分放并临时存储在szyProtocol类里面
                    //接收信息在此处进行处理；
                    
                    HCMainForm.socket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
                }
                else
                {
                    dispose(HCMainForm.socket);
                }
            }
            catch (Exception e) { }
        }


        /// <summary>
        /// 发送信息方法
        /// </summary>
        /// <param name="byteData">需要发送的信息</param>
        public void Send(Socket socket, string str)
        {
            //将string类型转换为byte数组
            var strToByte = Encoding.UTF8.GetBytes(str);
            try
            {
                socket.BeginSend(strToByte, 0, strToByte.Length, 0, new AsyncCallback(SendCallBack), null);
            }
            catch (Exception e)
            {
                MessageBox.Show("请连接Socket","Warning");
            }
        }


        /// <summary>
        /// 发送信息回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void SendCallBack(IAsyncResult ar)
        {
            try
            {
                Socket socket = (Socket)ar.AsyncState;
                socket.EndSend(ar);
            }
            catch (SocketException)
            {
            }
        }


        /// <summary>
        /// 检查Socket对象是否成功连接
        /// </summary>
        /// <param name="socket">需要检查连接的Socket对象</param>
        public bool IsConnect(Socket socket)
        {
            bool flag=false;
            bool blokingState = socket.Blocking;
            try
            {
                byte[] check = new byte[1];
                socket.Blocking = false;
                socket.Send(check, 0, 0);
                flag = true;
                return true;
            }
            catch (SocketException e)
            {
                //产生10035==WSAEWOULDBLOCK错误，说明被阻止了，但还是连接的
                if (e.NativeErrorCode.Equals(10035))
                {
                    flag = true;
                    return true;
                }
                else
                {
                    flag = false;
                    return false;
                }
            }
            catch(ObjectDisposedException)
            {
                MessageBox.Show("请连接Socket");
                flag = false;
                return false;
            }
            finally
            {
                if (flag == true)
                {
                    //检查完后恢复状态
                    socket.Blocking = blokingState;
                    flag = false;
                }
            }
        }

        /// <summary>
        /// 释放Socket资源
        /// </summary>
        public void dispose(Socket socket)
        {
            try
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
            catch (Exception)
            {

            }
        }



        public void sendByteData(Socket socket,byte[] data)
        {
            try
            {
                socket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendByteDataCallback), null);
            }
            catch (Exception e)
            {
                //MessageBox.Show("请连接Socket");
                //return;
            }
        }
        private void SendByteDataCallback(IAsyncResult ar)
        {
            try
            {
                Socket socket = (Socket)ar.AsyncState;
                socket.EndSend(ar);
            }
            catch (Exception)
            {

            }
        }

    }
 
}
